<template>
  <div class="app-container">
    <el-container>
      <el-aside width="250px" style="background-color: Transparent; padding: 20px 20px;  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1)">
        <el-input placeholder="部门名称/组织机构代码" v-model="queryValue"  suffix-icon="el-icon-search">
        </el-input>
        <div style="margin-top: 30px">
          <el-tree class="filter-tree" :data="[...departmentRoot]" ref="tree" :props="tree.defaultProps" :filter-node-method="filterDeptTree" :default-expand-all="true"></el-tree>
        </div>
      </el-aside>
      <el-main>
        <el-button v-waves type="primary" @click="handleAdd">添加部门</el-button>
        <el-table
          :data="table.data"
          row-key = "departmentId"
          :v-loading="table.dataLoading"
          ref="table"
          style="width: 100%;margin-top:30px;"
          border
        >
          <el-table-column align="center" label="部门名称">
            <template slot-scope="scope">
              {{ scope.row.departmentName }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="组织机构代码">
            <template slot-scope="scope">
              {{ scope.row.departmentCode }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="上级部门" >
            <template slot-scope="scope">
              {{ formatDepartmentParent(scope.row.parentId) }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="部门主管职位" >
            <template slot-scope="scope">
              {{formantPosition(scope.row.masterPositionId)}}
            </template>
          </el-table-column>
          <el-table-column align="center"  fixed="right" width="180px">
            <template slot-scope="scope">
              <el-button v-waves type="primary" size="small" @click="handleEdit(scope)">编辑</el-button>
              <el-button v-waves type="danger" size="small" @click="handleDelete(scope)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-main>
    </el-container>
    <el-dialog :visible.sync="dialog.visible" :title="dialog.title">
      <el-form :model="department" label-width="120px" label-position="left" style="margin: 0px 20px 0px 20px">
        <el-form-item label="部门名称">
          <el-input v-model="department.departmentName" placeholder="职位名称" />
        </el-form-item>
        <el-form-item label="组织机构代码">
          <el-input v-model="department.departmentCode" placeholder="职位代码" />
        </el-form-item>
        <el-form-item label="上级部门" v-show="!isRootDepartment">
          <el-select v-model="department.parentId" placeholder="请选择">
            <el-option
              v-for="item in table.data"
              :key="item.departmentId"
              :label="item.departmentName+ ' ( '+item.departmentCode+' ) '"
              :value="item.departmentId">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="部门职务">
          <div  v-show="showDutiesSelect">
            <el-select v-model="dutyIds" placeholder="请选择" :multiple="true" @change="clearDutySelect">
              <el-option
                v-for="item in departmentDuties"
                :key="item.dutyId"
                :label="item.dutyName"
                :value="item.dutyId"
                :disabled ='item.disabled'
              >
              </el-option>
            </el-select>
            <el-button size="small" style="margin-left: 10px"  @click="showDutiesSelect = false" >确定</el-button>
          </div>
          <div v-show="!showDutiesSelect">
            <el-tag v-for="item in deptDuties" :key="item.dutyId" type="" style="margin: 5px 5px 5px 5px;">{{item.dutyName}}</el-tag>
            <el-button size="small" @click="showDutiesSelect = true">修改</el-button>
          </div>
        </el-form-item>
        <el-form-item label="负责人职务" >
          <div  v-show="showDutiesSelect">
            <el-select v-model="department.masterDutyId" placeholder="请选择" >
              <el-option
                v-for="item in deptDuties"
                :key="item.dutyId"
                :label="item.dutyName"
                :value="item.dutyId"
              >
              </el-option>
            </el-select>
          </div>
          <div  v-show="!showDutiesSelect">
            <el-tag   type="" style="margin: 5px 5px 5px 5px;" v-show="masterDutyName" >{{ masterDutyName }}</el-tag>
          </div>
        </el-form-item>
      </el-form>
      <div style="text-align:right;">
        <el-button type="danger" @click="dialog.visible=false">取消</el-button>
        <el-button type="primary" @click="confirmSave">保存</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import waves from '@/directive/waves'
import { deepClone } from '@/utils'
import { list } from '@/api/position'
import { loadDuties } from '@/api/dict'
import { searchDept, deptInfo, addDept, editDept, disableDept } from '@/api/dept'

const defaultDepartment = {
  departmentId: null,
  departmentCode: null,
  departmentName: null,
  parentId: null,
  masterDutyId: null,
  duties: null,
  dutyIds: []
}

export default {
  directives: { waves },
  data() {
    return {
      table: {
        data: [],
        dataLoading: true
      },
      dialog: {
        visible: false,
        title: '',
        addTitle: '添加部门',
        editTitle: '编辑部门',
        type: '',
        addType: 'add',
        editType: 'edit'
      },
      tree: {
        defaultProps: {
          label: 'departmentName',
          children: 'nodes'
        }
      },
      isReadEdit: false,
      showDutiesSelect: false,
      dictDuties: [],
      queryValue: null,
      dutyIds: [],
      departmentDuties: [],
      departmentRoot: deepClone(defaultDepartment),
      departmentList: [],
      positionList: [],
      department: deepClone(defaultDepartment)
    }
  },
  watch: {
    queryValue(val) {
      this.filterDeptTable(val)
      this.$nextTick(() => {
        this.$refs.tree.filter(val)
      })
    },
    isReadEdit(val) {
      const duties = deepClone(this.dictDuties)
      if (!val) {
        this.departmentDuties = duties
        return
      }
      if (!this.dutyIds || this.dutyIds.length === 0) {
        this.departmentDuties = duties
        return
      }
      const disabledIds = this.dutyIds.filter(v => !duties.some(k => v === k.dutyId))
      if (disabledIds && disabledIds.length > 0) {
        const disableDuty = this.department.duties.filter(v => disabledIds.some(k => k === v.dutyId))
        duties.push(...disableDuty)
      }
      this.departmentDuties = duties
    }
  },
  computed: {
    deptDuties() { // 部门下属的职务
      let duties = []
      if (this.dutyIds && this.dutyIds.length > 0) {
        duties = this.departmentDuties.filter(v => this.dutyIds.some(k => v.dutyId === k))
      }
      return duties
    },
    masterDutyName() {
      if (!this.department.masterDutyId) {
        return ''
      }
      let master = this.department.masterDuty
      if (!master) {
        master = this.dictDuties.find(v => v.dutyId === this.department.masterDutyId)
      }
      if (master) {
        return master.dutyName
      }
      return ''
    },
    isRootDepartment() { // 是否顶级部门
      return this.department.departmentId && !this.department.parentId
    },
    routesData() {
      return this.routes
    }
  },
  created() {
    try {
      Promise.all([this.getPositionList(), this.loadDictDuties(), this.getTableList()])
    } catch (e) {
      console.log(e)
    }
  },
  methods: {
    async getPositionList() { // 获得职位列表
      this.positionList = await list()
    },
    async loadDictDuties() {
      this.dictDuties = await loadDuties()
    },
    async getTableList() { // 得到职位列表
      this.table.dataLoading = true
      this.departmentList = await searchDept()
      this.table.data = [...this.departmentList]
      this.departmentRoot = this.buildDepartmentTree(this.departmentList, null) // build tree
      this.table.dataLoading = false
    },
    async confirmSave() { // 提交新增或修改
      let notifyTitle = ''
      const { departmentCode, departmentName, parentId, masterDutyId } = this.department
      const request = {
        departmentName,
        departmentCode,
        parentId,
        masterDutyId,
        dutyIds: this.dutyIds
      }
      if (this.dialog.type === this.dialog.addType.toString()) {
        notifyTitle = '添加成功'
        await addDept(request)
      }
      if (this.dialog.type === this.dialog.editType.toString()) {
        notifyTitle = '修改成功'
        request.departmentId = this.department.departmentId
        await editDept(request)
      }
      const notify = { // notify
        title: `${notifyTitle}`,
        type: 'success',
        dangerouslyUseHTMLString: true,
        message: `<div>部门名称: ${departmentName}</div> <div>组织机构代码: ${departmentCode}</div>`
      }
      this.$notify(notify)
      this.dialog.visible = false// close dialog
      this.getTableList() // reload table
    },
    async handleEdit(scope) { // 执行修改职位
      this.showDutiesSelect = false
      this.dialog.type = this.dialog.editType.toString()
      this.dialog.title = this.dialog.editTitle.toString()
      this.dialog.visible = true // open dialog
      const departmentId = scope.row.departmentId // get Id
      this.department = await deptInfo(departmentId)// 获得部门信息
      this.dutyIds = [] // clear cache
      if (this.department.duties && this.department.duties.length > 0) {
        this.dutyIds = this.department.duties.map(v => v.dutyId)
      }
      this.isReadEdit = true
    },
    handleAdd() { // 执行添加职位
      this.department = deepClone(defaultDepartment)
      this.dialog.type = this.dialog.addType.toString()
      this.dialog.title = this.dialog.addTitle.toString()
      this.dialog.visible = true // open dialog
      this.showDutiesSelect = true
      this.dutyIds = []
      this.isReadEdit = false
    },
    handleDelete({ $index, row }) { // 执行删除职位
      this.$confirm('确认删除该部门 ?', 'Warning', {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(async() => {
          await disableDept(row.departmentId)
          this.table.data.splice($index, 1)
          this.$message({
            type: 'success',
            message: '删除成功'
          })
        })
        .catch(err => { console.error(err) })
    },
    buildDepartmentTree(departments, parent) { // 递归构建组织机构树
      if (parent === null) {
        departments.forEach(dept => {
          if (!dept.parentId) {
            parent = dept
          }
        })
      }
      departments.forEach(dept => {
        if (parent.departmentId === dept.parentId) {
          if (!parent.nodes) {
            parent.nodes = []
          }
          parent.nodes.push(dept)
          this.buildDepartmentTree(departments, dept)
          if (!dept.nodes || dept.nodes.length === 0) {
            return parent
          }
        }
      })
      return parent
    },
    filterDeptTree(value, data) { // 根据搜索条件过滤部门树
      if (!value) {
        return true
      }
      return data.departmentName.startsWith(value) || data.departmentCode.startsWith(value)
    },
    filterDeptTable(value) { // 根据搜索条件过滤部门表格
      this.table.dataLoading = true
      if (value && value.trim() !== '') {
        this.table.data = this.departmentList.filter(v => v.departmentName.startsWith(value) || v.departmentCode.startsWith(value))
      } else {
        this.table.data = [...this.departmentList]
      }
      this.table.dataLoading = false
    },
    formatDepartmentParent(parentId) {
      const parent = this.table.data.find(v => v.departmentId === parentId)
      return parent ? parent.departmentName : null
    },
    formantPosition(positionId) {
      const post = this.positionList.find(v => v.positionId === positionId)
      return post ? post.positionName : null
    },
    clearDutySelect() { // 部门职务联系部门主管select
      this.department.masterDutyId = null
    }
  }
}
</script>

<style lang="scss" scoped>
.app-container {
  .roles-table {
    margin-top: 30px;
  }
  .permission-tree {
    margin-bottom: 30px;
  }
}
</style>
